package x_selectionlistener;

import java.util.HashMap;
import java.util.LinkedList;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.texteditor.ITextEditor;

public class ClassTabChangeEventDispatcher implements IPartListener{
	private final static ClassTabChangeEventDispatcher instance =
		new ClassTabChangeEventDispatcher();
	
	private final HashMap<String, LinkedList<IClassTabChangeListener>> listeners =
		new HashMap<String, LinkedList<IClassTabChangeListener>>();
	
	private ClassTabChangeEventDispatcher(){}
	
	public static ClassTabChangeEventDispatcher getInstance(){
		return instance;
	}
	
	public void addClassTabChangeListenerForProject(IClassTabChangeListener newListener, String project){
		if(listeners.containsKey(project)){
			listeners.get(project).add(newListener);
		} else {
			LinkedList<IClassTabChangeListener> list = new LinkedList<IClassTabChangeListener>();
			list.add(newListener);
			listeners.put(project, list);
		}
		//System.out.println("[ClassTabChangeEventDispatcher] added a listener for project: " + project);
	}
	
	public void removeClassTabChangeListenerForProject(IClassTabChangeListener oldListener, String project){
		if(listeners.containsKey(project)){
			listeners.get(project).remove(oldListener);
		}
		//System.out.println("[ClassTabChangeEventDispatcher] removed a listener for project: " + project);
	}
	
	private boolean isListenedProject(String project){
		return project != null && listeners.containsKey(project);
	}
	
	private String[] getPackageAndClass (final IWorkbenchPart part){
		try{
			String[] packageAndClass = null;
			if(part instanceof ITextEditor) {
				final ITextEditor editor = (ITextEditor) part;
				final IEditorInput in = editor.getEditorInput();
				if (in instanceof IFileEditorInput) {
					final IFileEditorInput editorInput = (IFileEditorInput) in;
					if (JavaCore.isJavaLikeFileName(editorInput.getFile().getName())) {
						final ICompilationUnit unit =
							JavaCore.createCompilationUnitFrom(editorInput.getFile());
						final IType type = unit.findPrimaryType();
						
						if (type != null) {
							final String classProject =
								type.getPackageFragment().getJavaProject().getElementName();
							final String packageName =
								type.getPackageFragment().getElementName();
							final String className = type.getElementName();
							
							packageAndClass = new String[3];
							packageAndClass[0] = classProject;
							packageAndClass[1] = packageName;
							packageAndClass[2] = className;
						}
					}
				}			
			}
			if (packageAndClass != null) {
				/*
				System.out.println("[ClassTabChangeEventDispatcher] tab: "
						+ packageAndClass[0] + "." + packageAndClass[1] + "."
						+ packageAndClass[2]);
						*/
			}
			return packageAndClass;
		} catch (Exception e){
			e.printStackTrace();
			return null;
		}
	}

	public void partActivated(IWorkbenchPart part) {
		String[] classAndPackage = getPackageAndClass(part);
		if (classAndPackage != null) {
			String involvedProject = classAndPackage[0];
			if (isListenedProject(involvedProject)) {
				for (IClassTabChangeListener listener : listeners.get(involvedProject)) {
					listener.classTabActivated(classAndPackage[1],classAndPackage[2]);
				}
			}
		}
	}

	public void partBroughtToTop(IWorkbenchPart part) {
		String[] classAndPackage = getPackageAndClass(part);
		if(classAndPackage != null){
			String involvedProject = classAndPackage[0];
			if(isListenedProject(involvedProject)){
				for(IClassTabChangeListener listener : listeners.get(involvedProject)){
					listener.classTabBroughtToTop(classAndPackage[1], classAndPackage[2]);
				}
			}
		}
	}

	public void partClosed(IWorkbenchPart part) {
		String[] classAndPackage = getPackageAndClass(part);
		if (classAndPackage != null) {
			String involvedProject = classAndPackage[0];
			if (isListenedProject(involvedProject)) {
				for (IClassTabChangeListener listener : listeners.get(involvedProject)) {
					listener.classTabClosed(classAndPackage[1], classAndPackage[2]);
				}
			}
		}
	}

	public void partOpened(IWorkbenchPart part) {
		String[] classAndPackage = getPackageAndClass(part);
		if (classAndPackage != null) {
			String involvedProject = classAndPackage[0];
			if (isListenedProject(involvedProject)) {
				for (IClassTabChangeListener listener : listeners.get(involvedProject)) {
					listener.classTabOpened(classAndPackage[1], classAndPackage[2]);
				}
			}
		}
	}
	
	public void partDeactivated(IWorkbenchPart part) {}

}
